package init;


import java.util.EnumSet;
import java.util.Set;

import javax.servlet.DispatcherType;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;

import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlCleaner;
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;

/**
 * @HandlesTypes：容器启动的时候,会将@HandlesTypes该注解指定的所有类型以及子类(实现类、子接口等)传递过来；
 * 
 * 应用启动的时候,会运行onStartup方法
 * ServletContext：当前web应用的ServletContext对象
 * Set<Class<?>>：@HandlesTypes注解中填写类型的所有子类型
 * 
 * 使用ServletContext注册web组件(Servlet、Filter、Listener)
 */
@HandlesTypes(value = {})
public class MyServletContainerInitializer implements ServletContainerInitializer {
	
	@Override
	public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println( "所有传入类型：" + c );
		
		System.out.println("通过ServletContext注册Filter");
		// 注册Sentinel的filter
		javax.servlet.FilterRegistration.Dynamic filter = ctx.addFilter("registerFilter", CommonFilter.class);
		/*
		 * 所有访问的Web-URL就会被自动统计为Sentinel的资源，可以针对单个URL维度进行流控。
		 * 如果希望区分不同的HTTP_Method_Type，可以将HTTP_METHOD_SPECIFY设为true。例如：'/foo' -> 'GET:/foo'
		 */
		filter.setInitParameter(CommonFilter.HTTP_METHOD_SPECIFY, "true");
		filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
		
		/*
		 * 自定义UrlCleaner
		 * 该接口实现的作用是：
		 * 	1、将REST风格的url进行归类
		 * 	2、将资源文件进行屏蔽，不计入Sentinel资源
		 */
		UrlCleaner urlCleaner = new UrlCleaner() {
			@Override
			public String clean(String originUrl) {
				if (originUrl == null || originUrl.isEmpty()) 
		            return originUrl;

		        // 比如将满足 /foo/{id} 的 URL 都归到 /foo/*
		        if (originUrl.startsWith("/foo/")) 
		            return "/foo/*";
		        
		        // 不希望统计 *.jsp 的资源文件，可以将其转换为empty string(since 1.6.3)
		        if (originUrl.endsWith(".jsp")) 
		            return "";
		        return originUrl;
			}
		};
		/*
		 * 设置使用自定义UrlCleaner
		 * 	如果屏蔽该行代码，Sentinel会使用自带的DefaultUrlCleaner。
		 * 	对访问的url不做处理，直接进行返回。会续操作会对该接口的返回进行Sentinel的资源定义。
		 */
		WebCallbackManager.setUrlCleaner( urlCleaner );
		
		
//		System.out.println("通过ServletContext注册Servlet");
//		javax.servlet.ServletRegistration.Dynamic servlet = 
//				ctx.addServlet("registerServlet", new RegisterServlet());
//		servlet.addMapping("/register");
		
//		System.out.println("通过ServletContext注册Listener");
//		ctx.addListener( RegisterListener.class );
	}

}
